<template>
  <div class="coach-full-bg">
    <div class="coach-main-layout">
      <div class="chat-section">
        <div class="coach-title">
          <el-icon class="ai-icon"><User /></el-icon>
          <span>AI 智能教练</span>
        </div>
        <el-card class="chat-card" shadow="hover">
          <el-scrollbar class="chat-history" ref="chatScrollbar">
            <div v-for="(msg, idx) in chatHistory" :key="idx" :class="['chat-bubble', msg.role, { 'fade-in': true }]">
              <div class="bubble-content">
                <el-icon v-if="msg.role==='coach'" class="coach-avatar"><User /></el-icon>
                <template v-if="msg.image">
                  <img :src="msg.image" class="chat-img" />
                </template>
                <span v-else v-html="msg.text.replace(/\n/g, '<br>')"></span>
              </div>
            </div>
          </el-scrollbar>
          <div class="chat-input-row">
            <el-input
              v-model="userInput"
              placeholder="请输入你的问题..."
              @keyup.enter="sendMessage"
              :disabled="loading"
              clearable
              class="chat-input-custom"
            />
            <input
              ref="fileInput"
              type="file"
              accept="image/*"
              style="display: none"
              @change="handleImageUpload"
            />
            <el-button @click="triggerFileInput" :disabled="loading" type="success" round plain class="upload-image-btn">
              <el-icon style="margin-right:4px;">
                <svg viewBox="0 0 24 24" width="1em" height="1em"><path fill="currentColor" d="M12 5c-3.86 0-7 3.14-7 7s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm0 12c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm6.5-11l-1.41-1.41C16.09 3.21 14.11 2 12 2S7.91 3.21 6.91 4.59L5.5 6H2v2h2l3.6 7.59-1.35 2.44C5.16 18.37 6.48 20 8.24 20h7.52c1.76 0 3.08-1.63 2.99-3.97l-1.35-2.44L20 8h2V6h-3.5zM12 17c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z"/></svg>
              </el-icon>上传图片
            </el-button>
            <el-button
              class="send-btn"
              type="primary"
              :loading="loading"
              @click="sendMessage"
              round
              style="margin-left:2px;"
            >
              <el-icon style="margin-right:4px;"><svg viewBox="0 0 24 24" width="1em" height="1em"><path fill="currentColor" d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg></el-icon>发送
            </el-button>
          </div>
          <div v-if="imagePreview" class="image-preview">
            <img :src="imagePreview" alt="预览" />
            <el-button size="small" @click="removeImage" type="danger" plain>移除</el-button>
          </div>
        </el-card>
        <el-button
          class="clear-history-btn"
          type="danger"
          :icon="Delete"
          @click="clearChatHistory"
          title="清空聊天记录"
        >
          <template #icon><Delete /></template>
          清空聊天
        </el-button>
      </div>
      <div class="suggestion-section">
        <div class="suggestion-title">
          <el-icon class="ai-icon"><User /></el-icon>
          <span>推荐问答</span>
        </div>
        <transition-group name="card-fade" tag="div" class="suggestion-list">
          <el-card v-for="(item, idx) in sources" :key="idx" class="suggestion-card" shadow="hover">
            <div class="suggestion-q">Q: {{ item.question }}</div>
            <div class="suggestion-a">A: {{ item.answer }}</div>
          </el-card>
        </transition-group>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { User, Delete } from '@element-plus/icons-vue'
import { useUserStore } from '@/stores/user'

const userInput = ref('')
const loading = ref(false)
const chatHistory = ref([
  { role: 'coach', text: '你好，我是你的AI教练，有什么想问我的吗？' }
])
const sources = ref([])
const userStore = useUserStore()

let ws = null

const streamingCoachMsg = ref(null) // 新增：流式訊息暫存
const fileInput = ref(null)
const imagePreview = ref(null)
const imageBase64 = ref(null)
const chatScrollbar = ref(null)

const userId = localStorage.getItem('userid') || 'anonymous'
const threadId = 'web_thread'

const triggerFileInput = () => {
  fileInput.value && fileInput.value.click()
}

const handleImageUpload = (e) => {
  const file = e.target.files[0]
  if (!file) return
  const reader = new FileReader()
  reader.onload = (ev) => {
    imagePreview.value = ev.target.result
    imageBase64.value = ev.target.result.split(',')[1]
  }
  reader.readAsDataURL(file)
}

const removeImage = () => {
  imagePreview.value = null
  imageBase64.value = null
  if (fileInput.value) fileInput.value.value = ''
}

const scrollToBottom = () => {
  nextTick(() => {
    if (chatScrollbar.value && typeof chatScrollbar.value.scrollTo === 'function') {
      chatScrollbar.value.scrollTo({ top: 99999 }) // 保證拉到底
    }
  })
}

const connectWS = () => {
  ws = new WebSocket('ws://localhost:8000/ws/coach/')
  ws.onopen = () => {
    // 请求历史消息
    ws.send(JSON.stringify({
      type: 'history',
      user_id: userId,
      thread_id: threadId
    }))
    console.log('WebSocket 连接成功')
  }
  ws.onmessage = async (event) => {
    loading.value = false
    try {
      const data = JSON.parse(event.data)
      // ====== 流式訊息處理 ======
      if (data.type === 'stream' && data.delta) {
        // 若還沒開始流式，先 push 一個空訊息
        if (!streamingCoachMsg.value) {
          streamingCoachMsg.value = { role: 'coach', text: '' }
          chatHistory.value.push(streamingCoachMsg.value)
        }
        streamingCoachMsg.value.text += data.delta
        scrollToBottom()
        return
      }
      if (data.type === 'stream_end') {
        streamingCoachMsg.value = null
        sources.value = data.sources || []
        return
      }
      // ====== 原有訊息處理 ======
      if (data.type === 'history' && Array.isArray(data.history)) {
        // 填充历史消息
        chatHistory.value = data.history.map(msg => ({
          role: msg.role,
          text: msg.text,
          image: msg.image
        }))
        return
      }
      if (data.type === 'clear_history_success') {
        chatHistory.value = [
          { role: 'coach', text: '聊天记录已清空，有什么想问我的吗？' }
        ]
        sources.value = []
        return
      }
      if (data.response) {
        chatHistory.value.push({ role: 'coach', text: data.response })
        sources.value = data.sources || []
      } else if (data.type === 'image_result' && data.image_caption) {
        chatHistory.value.push({ role: 'coach', text: data.image_caption })
      } else if (data.error) {
        ElMessage.error(data.error)
      }
    } catch (e) {
      ElMessage.error('AI教练返回数据异常')
    }
  }
  ws.onerror = () => {
    ElMessage.error('WebSocket 连接出错')
  }
  ws.onclose = () => {
    setTimeout(connectWS, 2000)
  }
}

onMounted(async () => {
  connectWS()
  // 自动拉取用户信息并同步到userStore和localStorage
  const userid = localStorage.getItem('userid')
  if (userid) {
    try {
      const response = await (await import('@/utils/request')).default.get(`/user/profiles/${userid}/`)
      userStore.setUser(response)
      if (response.gender) localStorage.setItem('gender', response.gender)
      if (response.birthdate) localStorage.setItem('birthdate', response.birthdate)
      if (response.height) localStorage.setItem('height', response.height)
      if (response.weight) localStorage.setItem('weight', response.weight)
    } catch (e) {
      // 获取失败可忽略
    }
  }
})

onBeforeUnmount(() => {
  if (ws) ws.close()
})

watch(() => chatHistory.value.length, () => {
  scrollToBottom()
})

const getUserProfile = () => {
  let gender = userStore.gender.value || ''
  let birthdate = userStore.birthdate.value || ''
  let height = userStore.height.value || ''
  let weight = userStore.weight.value || ''
  // localStorage兜底
  if (!gender) {
    gender = localStorage.getItem('gender') || ''
    if (!gender) localStorage.setItem('gender', '')
  } else {
    localStorage.setItem('gender', gender)
  }
  if (!birthdate) {
    birthdate = localStorage.getItem('birthdate') || ''
    if (!birthdate) localStorage.setItem('birthdate', '')
  } else {
    localStorage.setItem('birthdate', birthdate)
  }
  if (!height) {
    height = localStorage.getItem('height') || ''
    if (!height) localStorage.setItem('height', '')
  } else {
    localStorage.setItem('height', height)
  }
  if (!weight) {
    weight = localStorage.getItem('weight') || ''
    if (!weight) localStorage.setItem('weight', '')
  } else {
    localStorage.setItem('weight', weight)
  }
  return { gender, birthdate, height, weight }
}

const sendMessage = () => {
  streamingCoachMsg.value = null // 新增：每次發送前重置
  if ((!userInput.value.trim() && !imageBase64.value) || !ws || ws.readyState !== 1) return

  if (imageBase64.value) {
    // 发送图片消息
    chatHistory.value.push({ role: 'user', text: '[图片]', image: imagePreview.value })
    scrollToBottom()
    ws.send(JSON.stringify({
      type: 'image',
      user_id: userId,
      thread_id: threadId,
      image_base64: imageBase64.value,
      user_profile: getUserProfile()
    }))
    removeImage()
    loading.value = true
    return
  }

  // 发送文本消息
  const input = userInput.value.trim()
  chatHistory.value.push({ role: 'user', text: input })
  scrollToBottom()
  userInput.value = ''
  loading.value = true
  ws.send(JSON.stringify({
    type: 'text',
    user_id: userId,
    thread_id: threadId,
    user_input: input,
    user_profile: getUserProfile()
  }))
}

const clearChatHistory = () => {
  if (ws && ws.readyState === 1) {
    ws.send(JSON.stringify({
      type: 'clear_history',
      user_id: userId,
      thread_id: threadId
    }))
  }
}
</script>

<style scoped>
:global(html, body, #app) {
  height: 100vh;
  overflow-x: hidden !important;
  margin: 0;
  padding: 0;
}
.coach-full-bg {
  min-height: 100vh;
  width: 100%;
  background: linear-gradient(120deg, #e0e7ff 0%, #f5f7fa 100%);
  display: flex;
  align-items: stretch;
  justify-content: center;
}
.coach-main-layout {
  display: flex;
  flex-direction: row;
  width: 100%;
  max-width: 1680px;
  margin: 0 auto;
  gap: 48px;
  box-sizing: border-box;
  justify-content: center;
  flex: 1 1 0;
  /* 移除 min-height: 100vh; 和 padding: 48px 0; */
}
.chat-section {
  flex: 7;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  padding-left: 48px;
  box-sizing: border-box;
}
.suggestion-section {
  flex: 3;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: flex-start;
  padding-right: 48px;
  box-sizing: border-box;
}
.coach-title, .suggestion-title {
  display: flex;
  align-items: center;
  font-size: 2.1rem;
  font-weight: bold;
  color: #4f46e5;
  margin-bottom: 28px;
  letter-spacing: 2px;
  gap: 12px;
  animation: fadeInDown 0.7s;
  user-select: none;
}
.ai-icon {
  font-size: 2.3rem;
}
.chat-card {
  width: 100%;
  height: 80%;
  display: flex;
  flex-direction: column;
  border-radius: 28px;
  box-shadow: 0 8px 32px rgba(79, 70, 229, 0.10);
  background: #fff;
  padding: 0 0 16px 0;
  transition: box-shadow 0.3s;
  border: 1.5px solid #e0e7ff;
}
.chat-card:hover {
  box-shadow: 0 16px 48px rgba(79, 70, 229, 0.13);
}
.chat-history {
  height: 68vh;
  overflow-y: auto;
  padding: 24px 28px 12px 28px;
  background: #f7f9fb;
  border-radius: 20px;
  margin-bottom: 12px;
  transition: background 0.3s;
  scrollbar-width: thin;
  scrollbar-color: #b3b8d1 #f7f9fb;
}
.chat-history::-webkit-scrollbar {
  width: 8px;
}
.chat-history::-webkit-scrollbar-thumb {
  background: #b3b8d1;
  border-radius: 6px;
}
.chat-history::-webkit-scrollbar-track {
  background: #f7f9fb;
}
.chat-bubble {
  display: flex;
  margin-bottom: 14px;
  opacity: 0;
  animation: bubbleFadeIn 0.5s forwards;
}
.chat-bubble.user {
  justify-content: flex-end;
}
.chat-bubble.coach {
  justify-content: flex-start;
}
.bubble-content {
  max-width: 80%;
  padding: 14px 22px;
  border-radius: 22px;
  font-size: 1.12rem;
  line-height: 1.8;
  box-shadow: 0 2px 12px rgba(90,103,216,0.08);
  background: #fff;
  color: #333;
  position: relative;
  transition: background 0.3s, color 0.3s;
  word-break: break-word;
}
.chat-bubble.user .bubble-content {
  background: linear-gradient(135deg, #6366f1 0%, #818cf8 100%);
  color: #fff;
  border-bottom-right-radius: 10px;
  box-shadow: 0 2px 16px rgba(99, 102, 241, 0.13);
}
.chat-bubble.coach .bubble-content {
  background: #fff;
  color: #4f46e5;
  border-bottom-left-radius: 10px;
}
.coach-avatar {
  margin-right: 10px;
  color: #6366f1;
  vertical-align: middle;
}
.chat-input-row {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-top: 10px;
  padding: 0 28px;
}
.suggestion-list {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 22px;
  justify-content: flex-start;
  margin-top: 18px;
}
.suggestion-card {
  width: 100%;
  border-radius: 22px;
  background: linear-gradient(120deg, #f1f5ff 0%, #f7f9fb 100%);
  box-shadow: 0 4px 20px rgba(99, 102, 241, 0.08);
  transition: transform 0.3s, box-shadow 0.3s;
  animation: cardFadeIn 0.7s;
  padding: 22px 26px 18px 26px;
  font-size: 1.08rem;
  border: 1.5px solid #e0e7ff;
  position: relative;
  overflow: hidden;
}
.suggestion-card:hover {
  transform: translateY(-6px) scale(1.03);
  box-shadow: 0 8px 32px rgba(99, 102, 241, 0.18);
}
.suggestion-q {
  font-weight: bold;
  color: #4f46e5;
  margin-bottom: 8px;
  font-size: 1.13rem;
  display: flex;
  align-items: center;
  gap: 8px;
}
.suggestion-q::before {
  content: "💡";
  font-size: 1.1em;
  margin-right: 4px;
}
.suggestion-a {
  color: #333;
  font-size: 1.01rem;
  margin-left: 2px;
}
/* 动画效果 */
@keyframes fadeInDown {
  from { opacity: 0; transform: translateY(-30px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(30px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes bubbleFadeIn {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes cardFadeIn {
  from { opacity: 0; transform: scale(0.95); }
  to { opacity: 1; transform: scale(1); }
}
.card-fade-enter-active, .card-fade-leave-active {
  transition: all 0.5s;
}
.card-fade-enter-from, .card-fade-leave-to {
  opacity: 0;
  transform: translateY(20px);
}
.image-preview, .chat-img {
  max-width: 180px;
  max-height: 180px;
  border-radius: 10px;
  margin: 8px 0;
  display: block;
}
.image-preview {
  margin-top: 10px;
}
.clear-history-btn {
  position: fixed;
  right: 48px;
  bottom: 110px;
  z-index: 100;
  box-shadow: 0 2px 8px rgba(99,102,241,0.10);
  border-radius: 16px;
  padding: 0 18px;
  height: 44px;
  font-size: 1.08rem;
  display: flex;
  align-items: center;
  font-weight: bold;
}
@media (max-width: 1200px) {
  .coach-main-layout {
    flex-direction: column;
    gap: 32px;
    padding: 24px 0;
    align-items: center;
    max-width: 100vw;
  }
  .chat-section, .suggestion-section {
    max-width: 100vw;
    align-items: stretch;
    padding-left: 0;
    padding-right: 0;
  }
  .suggestion-section {
    max-width: 700px;
    min-width: 0;
    align-items: stretch;
  }
}
@media (max-width: 700px) {
  .coach-main-layout {
    flex-direction: column;
    gap: 16px;
    padding: 10px 0;
    max-width: 100vw;
  }
  .chat-section, .suggestion-section {
    max-width: 100vw;
    align-items: stretch;
    padding-left: 0;
    padding-right: 0;
  }
  .suggestion-section {
    max-width: 100vw;
    min-width: 0;
    align-items: stretch;
  }
  .chat-card, .suggestion-card {
    border-radius: 12px;
    font-size: 0.99rem;
  }
  .coach-title, .suggestion-title {
    font-size: 1.25rem;
    margin-bottom: 12px;
  }
  .clear-history-btn {
    right: 12px;
    bottom: 12px;
  }
}
.send-btn {
  background: linear-gradient(120deg, #6366f1 0%, #818cf8 100%) !important;
  color: #fff !important;
  border-radius: 20px !important;
  border: none !important;
  font-weight: bold;
  box-shadow: 0 2px 8px rgba(99,102,241,0.10);
  transition: box-shadow 0.2s, transform 0.2s;
}
.send-btn:hover {
  box-shadow: 0 4px 16px rgba(99,102,241,0.18);
  transform: translateY(-2px) scale(1.04);
  color: #fff !important;
}
.upload-image-btn {
  background: linear-gradient(120deg, #6366f1 0%, #818cf8 100%) !important;
  color: #fff !important;
  border-radius: 20px !important;
  border: none !important;
  font-weight: bold;
  box-shadow: 0 2px 8px rgba(99,102,241,0.10);
  transition: box-shadow 0.2s, transform 0.2s;
}
.upload-image-btn:hover {
  box-shadow: 0 4px 16px rgba(99,102,241,0.18);
  transform: translateY(-2px) scale(1.04);
  color: #fff !important;
}
.chat-input-custom :deep(.el-input__wrapper) {
  border-radius: 22px !important;
  box-shadow: 0 2px 12px rgba(99,102,241,0.10);
  border: 2px solid transparent;
  background: linear-gradient(120deg, #f1f5ff 0%, #f7f9fb 100%) padding-box, linear-gradient(120deg, #6366f1 0%, #818cf8 100%) border-box;
  transition: box-shadow 0.2s, border-color 0.2s;
}
.chat-input-custom :deep(.el-input__wrapper.is-focus) {
  box-shadow: 0 4px 20px rgba(99,102,241,0.18);
  border-color: #6366f1 !important;
}
.chat-input-custom :deep(.el-input__inner) {
  background: transparent;
  border-radius: 22px;
  font-size: 1.08rem;
  color: #333;
  padding: 12px 18px;
}
</style> 